很多時候,我們有需要隱藏手法的時候,不論是阿嬤的秘密料理、魔術師的魔術、成功人士的成功方式,都有只有圈內人士才知道的秘密。而程式設計也是同樣道理的。
Photo by @1walter2 on Unsplash
Swift 的封裝可以透過不少方式,我們目前先討論 protocol:
// Swift
/* Point.swift */
protocol Point: AnyObject {
static func pointMake() -> Point
func getx(_:Point) -> Int
func gety(_:Point) -> Int
}
Swift 的 protocol 可以作為有前提的抽象類別,因此我們可以使用
let p: Point
的方式使用封裝。
接下來,我們圍繞這個 Point 來理解理解。
C 語言的存在封裝的特性,透過在 Header 公開宣告,告訴程式碼的其他部分只有這些是公開的,其他則是不公開的。
// C
/* point.h */
struct point;
typedef struct point point;
point* pointMake(void);
int getx(point*);
int gety(point*);
封裝或許在iOS 開發上可能用不太到,但是在 Library/Framework 的部分很值得討論。
首先請先看看下面這的 Public header。
// Objective-C
/* ITPoint.h */
#import <Foundation/Foundation.h>
@interface ITPoint : NSObject
+ (instancetype)make;
- (NSInteger)getx;
- (NSInteger)gety;
@end
這代表 Client 端可以呼叫到這三個函式。
而下面這個 header 檔沒有被納入 pubilc header 中
// Objective-C
/* ITPoint+internal.h */
#import "ITPoint.h"
@interface ITPoint ()
@property NSNumber * x;
@property NSNumber * y;
@end
也因為ITPoint.m
是圈內人士,可以知道所有的 header
// Objective-C
/* ITPoint.m */
#import "ITPoint.h"
#import "ITPoint+internal.h"
@implementation ITPoint
+ (instancetype) make {
ITPoint* p = [[self alloc] init];
return p;
}
- (NSInteger)getx {
return [self.x intValue]; // self.x 屬於 internal
}
- (NSInteger)gety {
return [self.y intValue]; // self.y 屬於 internal
}
@end
如此一來,NSNumber* x
與 NSNumber* y
就會在不知不覺的情況下,進入到 Client 的程式碼內了!
struct point;
是什麼? 他的目的是什麼?let h: Hashable